<?php
abstract class CodeSpace_ServiceClient_Abstract
{
    const REQUEST_CREATE = 'CREATE';
    const REQUEST_READ = 'READ';
    const REQUEST_UPDATE = 'UPDATE';
    const REQUEST_DELETE = 'DELETE';
    
    protected $_gatewayAddress = 'http://morpheus.gateway.mkb.com';
    protected $_gatewayPort = '41000';
    

    protected $_serviceIdentity = null;

    
    /**
     * Base URL of Authentication Service Provider
     * @access private
     * @var string
     */
    protected $_requestParameters = null;

    
    /**
     * Access Token that is used for secured(oauth) data transfer
     * @access private
     * @var string
     */
    protected $_accessToken = null;

    /**
     * Consumer Key is the Client Identifier and it is used to  
     * identify the client at the server side
     * @access private
     * @var string
     */
    protected $_consumerKey = null;

    /**
     * consumer Secret that is used for hashing the request data
     * @access private
     * @var string
     */
    protected $_consumerSecret = null;

    public function __construct ()
    {
        $configFile = APPLICATION_PATH . '/configs/client_identifier.ini';
        
        if (file_exists($configFile))
        {
            $options['nestSeparator'] = ':';
            $config = new Zend_Config_Ini($configFile, 'consumer', $options);
            $this->setConsumerKey($config->key);
            $this->setConsumerSecret($config->secret);
            $this->setAccessToken($config->access_token, $config->access_token_secret);            
        }
    }

    public function setConsumerKey ($key)
    {
        $this->_consumerKey = $key;
    }

    public function setConsumerSecret ($secret)
    {
        $this->_consumerSecret = $secret;
    }

    public function setAccessToken ($token, $secret)
    {
        $accessToken = new Zend_Oauth_Token_Access();
        $accessToken->setToken($token);
        $accessToken->setTokenSecret($secret);
        $this->_accessToken = $accessToken;
    }

    public function getRequestUrl ()
    {
        $url = $this->_gatewayAddress;
        if (! is_null($this->_gatewayPort))
        {
            $url .= ':' . $this->_gatewayPort;
        }
        return $url;
    }
    
    public function getRequestTokenUrl()
    {
        $requestUrl = $this->getRequestUrl();
        return $requestUrl . '/oauth/requesttoken';
    }
    
    public function getAccessTokenUrl()
    {
        $requestUrl = $this->getRequestUrl();
        return $requestUrl . '/oauth/accesstoken';
    }
    
    public function getAuthorizationUrl()
    {
        $requestUrl = $this->getRequestUrl();
        return $requestUrl . '/oauth/authorization';
    }
    
    public function getRequestParameters ()
    {
        $oauthParams = $this->_prepareRequestParameters();
        $this->_requestParameters['service_identity'] = $this->_serviceIdentity;
        $requestParams = array_merge($oauthParams, $this->_requestParameters);
        // Create Signature
        
        
        $utility = new Zend_Oauth_Http_Utility;
        $sign = $utility->sign(
            $requestParams,
            $requestParams['oauth_signature_method'],
            $this->_consumerSecret,
            $this->_accessToken->getTokenSecret(),
            'POST',
            'http://morpheus.gateway.mkb.com:41000/service'
        );
        
        $requestParams['oauth_signature'] = $sign;
        $this->reset();
        return $requestParams;
        /*
        $crypt = new Zend_Oauth_Signature_Hmac($this->_consumerSecret, 
        $this->_accessTokenSecret, 'SHA1');
        $signature = $crypt->sign($requestParams);
        $requestParams['oauth_signature'] = $signature;
        $this->reset();
        return $requestParams;
        */
    }

    /**
     * 
     * setRequestParameter
     * 
     * Sets the proccess specific parameters, and merge them
     * with the oauth security parameters
     * Also It signs the paramters
     * 
     * @author Tolga Akyüz <tolga@mikrobeta.com.tr>
     * @access public
     * @param array Associative array that you want to send to the server
     */
    public function setRequestParameter ($key, $value)
    {
        $this->_requestParameters[$key] = $value;
    }

    public function setRequestParameters ($params)
    {
        foreach ($params as $key => $value)
        {
            $this->setParameter($key, $value);
        }
    }

    /**
     * 
     * Prepares the parameters that is required for 
     * a secure oauth request
     * 
     * @author Tolga Akyüz <tolga@mikrobeta.com.tr>
     * @access private
     * @return array Returns a associative array which is needed for oauth
     */
    private function _prepareRequestParameters ()
    {
        $params = array ();
        $params['oauth_consumer_key'] = $this->_consumerKey;
        $params['oauth_nonce'] = md5(uniqid(rand(), true));
        $params['oauth_signature_method'] = 'HMAC-SHA1';
        $params['oauth_timestamp'] = time();
        $params['oauth_token'] = $this->_accessToken->getToken();
        $params['oauth_version'] = '1.0';
        return $params;
    }

        /**
     * 
     * Reset
     * 
     * Rests the all request parameters in order to
     * allow another request
     * 
     * @author Tolga Akyüz <tolga@mikrobeta.com.tr>
     * @access public
     */
    public function reset ()
    {
        $this->_requestParameters = null;
    }
    
    private function _prepareConsumerForRequest()
    {
        $consumer = new Zend_Oauth_Consumer();
    	$consumer->setConsumerKey($this->_consumerKey);
    	$consumer->setConsumerSecret($this->_consumerSecret);
    	$consumer->setRequestScheme(Zend_Oauth::REQUEST_SCHEME_POSTBODY);
    	$consumer->setCallbackUrl('http://localhost:10088/client_application/index/authenticationdone');
    	$consumer->setRequestTokenUrl($this->getRequestTokenUrl());
    	$consumer->setAccessTokenUrl($this->getAccessTokenUrl());
    	$consumer->setUserAuthorizationUrl($this->getAuthorizationUrl());
   		
   		return $consumer;
    }
    
    
    public function authenticateUser()
    {
        $consumer = $this->_prepareConsumerForRequest();
        $token = $consumer->getRequestToken();
        
        // Sets the request token to the Session
        $oauthSession = new Zend_Session_Namespace('oauth');
        $oauthSession->oauth_token = $token->getToken();
        $oauthSession->oauth_token_secret = $token->getTokenSecret(); 
        $oauthSession->lock();
        $oauthSession->setExpirationSeconds(200);
        // Redirect for authentication
   		$consumer->redirect();
    }
    
    public function requestAccessToken()
    {
        $oauthSession = Zend_Session::namespaceGet('oauth');
        
        $requestToken = $oauthSession['oauth_token'];
        $requestTokenSecret = $oauthSession['oauth_token_secret'];
        
    	$tokenRequest = new Zend_Oauth_Token_Request();
    	$tokenRequest->setToken($requestToken);
		$tokenRequest->setTokenSecret($requestTokenSecret);
		
		$consumer = $this->_prepareConsumerForRequest();
        	
   		$token = $consumer->getAccessToken($oauthSession, $tokenRequest);
   		$this->_accessToken = $token;
   		Zend_Session::namespaceUnset('oauth');
   		return $token;
    }
}
?>